package com.ds.plugins.action;

import com.alibaba.fastjson.JSONObject;
import com.ds.annotation.Aggregation;
import com.ds.annotation.AggregationType;
import com.ds.annotation.Split;
import com.ds.annotation.UserSpace;
import com.ds.common.JDSException;
import com.ds.common.logging.ChromeProxy;
import com.ds.config.ResultModel;
import com.ds.context.JDSActionContext;
import com.ds.esd.annotation.CustomAnnotation;
import com.ds.esd.annotation.MenuBarMenu;
import com.ds.esd.annotation.event.CustomBeforInvoke;
import com.ds.esd.annotation.event.CustomOnExecueSuccess;
import com.ds.esd.annotation.field.APIEventAnnotation;
import com.ds.esd.annotation.menu.CustomMenuType;
import com.ds.esd.annotation.ui.ComponentType;
import com.ds.esd.annotation.ui.RequestPathEnum;
import com.ds.esd.bean.ComponentBean;
import com.ds.esd.bean.CustomViewBean;
import com.ds.esd.bean.MethodConfig;
import com.ds.esd.bean.WidgetBean;
import com.ds.esd.bean.field.combo.CustomModuleRefFieldBean;
import com.ds.esd.dsm.BuildFactory;
import com.ds.esd.dsm.DSMFactory;
import com.ds.esd.dsm.aggregation.DomainInst;
import com.ds.esd.dsm.java.AggRootBuild;
import com.ds.esd.engine.ESDFacrory;
import com.ds.esd.engine.EUModule;
import com.ds.esd.tool.component.Component;
import com.ds.esd.tool.component.ComponentList;
import com.ds.esd.tool.properties.Properties;
import com.ds.web.util.JSONGenUtil;
import org.mvel2.templates.TemplateRuntime;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;


@Controller
@RequestMapping(value = {"/action/component/build/"})
@MenuBarMenu(menuType = CustomMenuType.TOP, caption = "组件编译", index = 6, imageClass = "spafont spa-icon-alignw")
@Aggregation(type = AggregationType.MENU, userSpace = UserSpace.SYS)
public class ComponentBuildAction {
    public ComponentBuildAction() {

    }


    @Split
    @CustomAnnotation(index = 2)
    @ResponseBody
    public ResultModel<Boolean> split() {
        ResultModel resultModel = new ResultModel();
        return resultModel;
    }


    @RequestMapping(method = RequestMethod.POST, value = "reBuildModule")
    @CustomAnnotation(index = 0, caption = "更新组件", imageClass = "xuicon xui-refresh")
    @APIEventAnnotation(customRequestData = {RequestPathEnum.SPA_PROJECTNAME, RequestPathEnum.SPA_CLASSNAME, RequestPathEnum.RAD_JSON, RequestPathEnum.RAD_SELECTITEMS})
    @ResponseBody
    public ResultModel<Boolean> rePackage(String currentClassName, String projectName, String[] json, String[] selectItems) {
        ResultModel result = new ResultModel<>();
        try {
            EUModule euModule = ESDFacrory.getAdminESDClient().getModule(currentClassName, projectName);
            MethodConfig methodConfig = euModule.getComponent().getMethodAPIBean();
            if (methodConfig == null) {
                methodConfig = ESDFacrory.getAdminESDClient().getMethodAPIBean(euModule.getPath(), projectName);
            }
            Map<String, Object> ctxMap = new HashMap<>();
            JDSActionContext.getActionContext().getContext().putAll(ctxMap);
            for (String currCom : selectItems) {
                Component component = euModule.getComponent().findComponentByAlias(currCom);
                if (component != null) {
                    CustomViewBean customViewBean = null;
                    ComponentBean componentBean = methodConfig.getView().findComByPath(component.getPath());
                    if (componentBean instanceof CustomViewBean) {
                        customViewBean = (CustomViewBean) componentBean;
                    } else if (componentBean instanceof WidgetBean) {
                        customViewBean = ((WidgetBean) componentBean).getViewBean();
                    } else if (componentBean instanceof CustomModuleRefFieldBean) {
                        CustomModuleRefFieldBean refFieldBean = (CustomModuleRefFieldBean) componentBean;
                        customViewBean = refFieldBean.getModuleBean().getMethodConfig().getView();
                    }

                    EUModule module = customViewBean.getMethodConfig().getModule(JDSActionContext.getActionContext().getContext(), projectName);
                    if (module != null) {
                        AggRootBuild aggRootBuild = BuildFactory.getInstance().getAggRootBuild(customViewBean, module.getClassName(), projectName);
                        if (aggRootBuild != null) {
                            aggRootBuild.reBuildModule();
                        }
                    }
                }
            }

            result.setCtx(ctxMap);
        } catch (JDSException e) {
            e.printStackTrace();
        }

        return result;
    }


    @RequestMapping(method = RequestMethod.POST, value = "clear")
    @CustomAnnotation(index = 0, caption = "重新编译", imageClass = "spafont spa-icon-c-comboinput")
    @APIEventAnnotation(customRequestData = {RequestPathEnum.SPA_PROJECTNAME, RequestPathEnum.SPA_CLASSNAME, RequestPathEnum.RAD_JSON, RequestPathEnum.RAD_SELECTITEMS}, onExecuteSuccess = {CustomOnExecueSuccess.MESSAGE}
            , beforeInvoke = CustomBeforInvoke.BUSY)
    @ResponseBody
    public ResultModel<Boolean> clear(String currentClassName, String projectName, String[] json, String[] selectItems) {
        ResultModel result = new ResultModel<>();
        try {
            EUModule euModule = ESDFacrory.getAdminESDClient().getModule(currentClassName, projectName);
            MethodConfig methodConfig = null;
            try {
                methodConfig = euModule.getComponent().getMethodAPIBean();
                if (methodConfig == null) {
                    methodConfig = ESDFacrory.getAdminESDClient().getMethodAPIBean(euModule.getPath(), projectName);
                }
            } catch (Throwable e) {
                e.printStackTrace();
            }
            DomainInst domainInst = DSMFactory.getInstance().getDomainInstById(methodConfig.getDomainId());
            Map<String, Object> ctxMap = new HashMap<>();
            ctxMap.put("domainId", domainInst.getDomainId());
            JDSActionContext.getActionContext().getContext().putAll(ctxMap);
            ComponentList components = new ComponentList();
            for (String objjson : json) {
                JSONObject obj = JSONObject.parseObject(objjson);
                if (obj != null && obj.getString("key") != null) {
                    String classType = obj.getString("key");
                    Component component = JSONObject.parseObject(obj.toJSONString(), (Class<Component>) ComponentType.fromType(classType).getClazz());
                    JSONObject property = obj.getJSONObject("properties");
                    //兼容版本，后期会移除
                    String tagter = obj.getString("tagter");
                    if (tagter != null) {
                        component.setTarget(tagter);
                    }
                    if (property != null) {
                        String propertyJson = obj.getJSONObject("properties").toJSONString();
                        Map context = JDSActionContext.getActionContext().getContext();
                        propertyJson = (String) TemplateRuntime.eval(propertyJson, context);
                        Class clazz = ComponentType.fromType(classType).getClazz();
                        Type realType = JSONGenUtil.getRealType(clazz, Properties.class);
                        if (realType != null) {
                            Properties properties = JSONObject.parseObject(propertyJson, realType);
                            component.setProperties(properties);
                        }
                    }
                    components.add(component);
                }

            }


            for (String currCom : selectItems) {
                Component component = euModule.getComponent().findComponentByAlias(currCom);
                if (component != null) {
                    CustomViewBean customViewBean = null;
                    ComponentBean componentBean = methodConfig.getView().findComByPath(component.getPath());

                    if (componentBean != null) {
                        componentBean = methodConfig.getView().findComByAlias(currCom);
                    }

                    if (componentBean instanceof CustomViewBean) {
                        customViewBean = (CustomViewBean) componentBean;
                    } else if (componentBean instanceof WidgetBean) {
                        customViewBean = ((WidgetBean) componentBean).getViewBean();
                    } else if (componentBean instanceof CustomModuleRefFieldBean) {
                        CustomModuleRefFieldBean refFieldBean = (CustomModuleRefFieldBean) componentBean;
                        customViewBean = refFieldBean.getModuleBean().getMethodConfig().getView();
                    }

                    EUModule module = customViewBean.getMethodConfig().getModule(JDSActionContext.getActionContext().getContext(), projectName);
                    if (module != null) {
                        AggRootBuild aggRootBuild = BuildFactory.getInstance().getAggRootBuild(customViewBean, module.getClassName(), projectName);
                        if (aggRootBuild != null) {
                            aggRootBuild.reBuildModule();
                        }
                    }
                }
            }
            result.setCtx(ctxMap);
        } catch (JDSException e) {
            e.printStackTrace();
        }

        return result;
    }


    public ChromeProxy getCurrChromeDriver() {
        ChromeProxy chrome = JDSActionContext.getActionContext().Par("$currChromeDriver", ChromeProxy.class);
        return chrome;
    }
}
